#ifndef MINIBASIC_USER_MEMORY_H
#define MINIBASIC_USER_MEMORY_H

#pragma once

#include "stdafx.h"
#include <objidl.h>

namespace MiniBasic
{
    class MemoryArea : public IStream
    {
        BYTE* base;
        BYTE* end;
        BYTE* currentPointer;
        LONG refCount;

    public:
        MemoryArea(const SIZE_T& bytesToAllocate); // throws HRESULT
        ~MemoryArea();

        ULONG_PTR Size() const;

        // IUnknown
        STDMETHODIMP QueryInterface(REFIID iid, void** ppvObject);
        STDMETHODIMP_(ULONG) AddRef(void);
        STDMETHODIMP_(ULONG) Release(void);

        // ISequentialStream Interface
        STDMETHODIMP Read(void* pv, ULONG cb, ULONG* pcbRead);
        STDMETHODIMP Write(void const* pv, ULONG cb, ULONG* pcbWritten);

        // IStream Interface
        STDMETHODIMP SetSize(ULARGE_INTEGER);
        STDMETHODIMP CopyTo(IStream*, ULARGE_INTEGER, ULARGE_INTEGER*, ULARGE_INTEGER*);
        STDMETHODIMP Commit(DWORD);
        STDMETHODIMP Revert(void);
        STDMETHODIMP LockRegion(ULARGE_INTEGER, ULARGE_INTEGER, DWORD);
        STDMETHODIMP UnlockRegion(ULARGE_INTEGER, ULARGE_INTEGER, DWORD);
        STDMETHODIMP Clone(IStream **);
        STDMETHODIMP Seek(LARGE_INTEGER liDistanceToMove, DWORD dwOrigin, ULARGE_INTEGER* lpNewFilePointer);
        HRESULT STDMETHODCALLTYPE Stat(STATSTG* pStatstg, DWORD grfStatFlag);
    };
}

#endif
